package cc.mrbird.febs.common.oss;

import cc.mrbird.febs.common.exception.FebsException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;
import org.joda.time.DateTime;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class OssConfig {

    static String[] TYPESTR = {".png",".jpg",".gif",".jpeg",".doc",".docx",".xlsx",".pdf",".wmv",".mp4",".mp3"};

    public OSS ossClient = getOssClient();

    /**
     * @ Description:
     * @ Param: []
     * @ return: com.aliyun.oss.OSS
     * @ Author: 马超伟
     * @ Date: 2020/4/15
     */
    public static OSS getOssClient() {
        OSS ossClient = new OSSClientBuilder().build(OSSConstant.END_POINT, OSSConstant.ACCESS_KEY_ID, OSSConstant.ACCESS_KEY_SECRET);
        ossClient.setBucketAcl(OSSConstant.BUCKET_NAME, CannedAccessControlList.PublicRead);
        return ossClient;
    }



    /**
    * @ Description: 阿里云文件上传方法
    * @ Param: [file, basePath]
    * @ return: java.lang.String
    * @ Author: 马超伟
    * @ Date: 2020/4/15
    */
    public static String upload(MultipartFile file, String basePath) {
        Boolean flag = false;
        for (String type : TYPESTR) {
            if (StringUtils.endsWithIgnoreCase(file.getOriginalFilename(), type)) {
                flag = true;
                break;
            }
        }
        if (!flag) {
            throw new FebsException("文件格式不正确");
        }

        String uploadUrl = "";
        try {
//            //2、怎么判断文件内容—> 如果我上传的是rm -rf /* 脚本
//            BufferedImage image = ImageIO.read(file.getInputStream());
//            if (image == null) {
//                throw new FebsException("文件内容不正确");
//                return "文件内容不正确";
//            } else {
//                System.err.println(image.getHeight());
//                System.err.println(image.getWidth());
//            }
            //判断oss实例是否存在：如果不存在则创建，如果存在则获取
            OSS ossClient = getOssClient();
            if (!ossClient.doesBucketExist(OSSConstant.BUCKET_NAME)) {
                //创建bucket
                ossClient.createBucket(OSSConstant.BUCKET_NAME);
                //设置oss实例的访问权限：公共读
                ossClient.setBucketAcl(OSSConstant.BUCKET_NAME, CannedAccessControlList.PublicRead);
            }
            //获取上传文件流
            InputStream inputStream = file.getInputStream();

            //构建日期路径：avatar/2019/02/26/文件名
            String filePath = new DateTime().toString("yyyy/MM/dd");

            //文件名：uuid/原始文件名到后缀
            String original = file.getOriginalFilename();
            String fileName = UUID.randomUUID().toString().replace("-","");
//            String fileType = original.substring(original.lastIndexOf("."));
            String newName = fileName +"/"+ original;
            String fileUrl = basePath+"/" + filePath + "/" + newName;
            //文件上传至阿里云
            ossClient.putObject(OSSConstant.BUCKET_NAME, fileUrl, inputStream);

            // 关闭OSSClient。
            ossClient.shutdown();

            //获取url地址
            uploadUrl =  OSSConstant.FILE_HOST+"/"+fileUrl;

        } catch (IOException e) {
           throw new FebsException("文件上传异常！");
        }
        return uploadUrl;
    }



    /**
     * 实现阿里云OSS的文件预览功能
     * @param objectName
     */
   /* public static  void previewOss(String objectName){
        OSS ossClient = getOssClient();
        //文档预览 获取 signURL
        String  process = "imm/previewdoc,copy_1";
        ossClient.
        JSONObject params = {};
        params.update({bucket.PROCESS: process})
        url = bucket.sign_url("GET", objectKey, 3600, params=params)

    }*/

    /**
     * @param ossClient  oss客户端
     * @param bucketName bucket名称
     * @return List<String>  文件路径和大小集合
     * @Title: queryAllObject
     * @ Description: 查询某个bucket里面的所有文件
     */
    public static List<String> queryAllObject(OSS ossClient, String bucketName) {
        List<String> results = new ArrayList<String>();
        try {
            // ossClient.listObjects返回ObjectListing实例，包含此次listObject请求的返回结果。
            ObjectListing objectListing = ossClient.listObjects(bucketName);
            // objectListing.getObjectSummaries获取所有文件的描述信息。
            for (OSSObjectSummary objectSummary : objectListing.getObjectSummaries()) {
                results.add(" - " + objectSummary.getKey() + "  " + "(size = " + objectSummary.getSize() + ")");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return results;
    }




    /**
     * 从阿里云下载单个文件
     *
     * @param objectName
     * @return
     */
    public static void download(String objectName, HttpServletResponse response) {
        BufferedInputStream input = null;
        OutputStream outputStream = null;
        OSSObject ossObject = null;
        try {
            String host = "http://file.huistone.com/";
            objectName = objectName.replace(host,"");
            response.reset();
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/x-msdownload");
            String substring = objectName.substring(objectName.lastIndexOf("/") + 1);
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(substring, "UTF-8"));
            // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
            ossObject = getOssClient().getObject(OSSConstant.BUCKET_NAME, objectName);
            input = new BufferedInputStream(ossObject.getObjectContent());
            byte[] buffBytes = new byte[1024];
            outputStream = response.getOutputStream();
            int read = 0;
            while ((read = input.read(buffBytes)) != -1) {
                outputStream.write(buffBytes, 0, read);
            }
        } catch (IOException ex) {
//            ex.printStackTrace();
        } finally {
            try {
                if (outputStream != null) {
                    outputStream.flush();
                    outputStream.close();
                }
                if (input != null) {
                    input.close();
                }
                if (ossObject != null) {
                    ossObject.close();
                }
            } catch (IOException e) {
//                e.printStackTrace();
            }
        }
    }


    /**
     * 文件及文件夹的递归删除
     *
     * @param file
     */
    private static void deleteFile(File file) {
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (File f : files) {
                deleteFile(f);
                //将循环后的空文件夹删除
                if (f.exists()) {
                    f.delete();
                }
            }
        } else {
            file.delete();
        }
    }




}
